#include<avr/io.h>
#include "Twi_eeprom.h"

#define START		0x08
#define REP_START	0x10
#define MT_SLA_ACK	0x18
#define MT_DATA_ACK	0x28
#define MR_SLA_ACK	0x40
#define MR_SLA_NACK	0x48
#define MR_DATA_NACK	0x58
#define MR_DATA_ACK	0x50
#define STATUS_MASK  (1<<TWS7 | 1<<TWS6| 1<<TWS5 | 1<<TWS4 | 1<<TWS3)
#define STATUS (TWSR & STATUS_MASK)
#define SETBIT(ADDRESS, BIT)    (ADDRESS |= (1 << BIT))
#define CLEARBIT(ADDRESS, BIT)  (ADDRESS &= ~(1 << BIT))
#define CHECKBIT(ADDRESS, BIT)  (ADDRESS & (1 << BIT))
#define TRUE  1
#define FALSE 0



//Complete Twi memory function init read write.


void TWI_init(char,char,char ); // pass bitrate in field 1, prescalar bits PB1,PB0 (individual) in field 2 and 3;
uint8_t TWI_write_byte(uint8_t ,uint16_t , char );//NOTE: The device address should be in the seven MSB's the last 8th bit must be left blank
char TWI_read_byte(uint8_t ,uint16_t );


/*________________Functions Here__________________________*/
void TWI_init(char BR,char PS1,char PS0 )	// BR = 0x08            PS0 = 1          PS1 =0 use TWI_init(0x08,0,1);
{
	TWBR = BR;							//TWI Bit rate register
	TWSR|=(PS1<<TWPS1)|(PS0<<TWPS0); //TWI status reg
}

char TWI_read_byte(uint8_t device_address,uint16_t memory_address)
{
	unsigned char data;
	//Initiate a Dummy Write Sequence to start Random Read
	
	
	do
	{
		//Put Start Condition on TWI Bus
		TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
		//Wait Till Done
		while(!(TWCR & (1<<TWINT)));
		if((STATUS != START) && (STATUS != REP_START))
			return FALSE;
		//Write SLA+W to EEPROM @ 00h
		TWDR=(device_address & 0xFE);            //1010 000 0;	
		//Initiate Transfer
		TWCR=(1<<TWINT)|(1<<TWEN);
		//Wait Till Done
		while(!(TWCR & (1<<TWINT)));
	}
        while(STATUS != MT_SLA_ACK);
	//Write ADDRH
	TWDR=(memory_address >> 8);
	//Initiate Transfer
	TWCR=(1<<TWINT)|(1<<TWEN);
	//Wait Till Done
	while(!(TWCR & (1<<TWINT)));
	if(STATUS != MT_DATA_ACK)
		return FALSE;
	//Write ADDRL
	TWDR=memory_address;
	//Initiate Transfer
	TWCR=(1<<TWINT)|(1<<TWEN);
	//Wait Till Done
	while(!(TWCR & (1<<TWINT)));
	if(STATUS != MT_DATA_ACK)
		return FALSE;

	//********************** End dummy write sequence *******************
	//Put Start Condition on TWI Bus
	TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
	//Wait Till Done
	while(!(TWCR & (1<<TWINT)));
	if(STATUS != REP_START)
          return FALSE;
	//Write SLA+R to EEPROM @ 00h
	TWDR=(device_address | 0x01);            //1010 000 1
	//Initiate Transfer
	TWCR=(1<<TWINT)|(1<<TWEN);
	//Wait Till Done
	while(!(TWCR & (1<<TWINT)));
	if(STATUS != MR_SLA_ACK)
          return FALSE;
	//Enable Reception of data by clearing TWINT
	TWCR=(1<<TWINT)|(1<<TWEN);
	//Wait till done
	while(!(TWCR & (1<<TWINT)));
	if(STATUS != MR_DATA_NACK)
          return FALSE;
	//Read the data
	data=TWDR;
	//Put Stop Condition 
	TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
	//Wait for STOP to finish
	while(TWCR & (1<<TWSTO));
	//Return TRUE
	return data;
}


uint8_t TWI_write_byte(uint8_t device_address,uint16_t memory_address, char data)//NOTE: The device address should be in the seven MSB's the last 8th bit must be left blank
{
	
	do
	{
		//Send START Condition
		TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
		//Wait for TWINT flag set
		while(!(TWCR & (1<<TWINT)));
		if((STATUS != START) && (STATUS != REP_START))
			return FALSE;
		//Write SLA+W to EEPROM @ 00h
		TWDR = (device_address & 0xFE);                  //1010 000 0
		//Initiate Transfer
		TWCR=(1<<TWINT)|(1<<TWEN);
		//Wait Till Done
		while(!(TWCR & (1<<TWINT)));
	}
        while(STATUS != MT_SLA_ACK);
	//Write ADDRH
	TWDR=(memory_address >> 8);
	//Initiate Transfer
	TWCR=(1<<TWINT)|(1<<TWEN);
	//Wait Till Done
	while(!(TWCR & (1<<TWINT)));
	if(STATUS != MT_DATA_ACK)
		return FALSE;
        
	//Write ADDRL
	TWDR= memory_address;
	//Initiate Transfer
	TWCR=(1<<TWINT)|(1<<TWEN);
	//Wait Till Done
	while(!(TWCR & (1<<TWINT)));
	if(STATUS != MT_DATA_ACK)
		return FALSE;
        
	//Write DATA
	TWDR=(data);
	//Initiate Transfer
	TWCR=(1<<TWINT)|(1<<TWEN);
	//Wait Till Done
	while(!(TWCR & (1<<TWINT)));
	if(STATUS != MT_DATA_ACK)
		return FALSE;
        
	//Put Stop Condition 
	TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
	//Wait for STOP to finish
	while(TWCR & (1<<TWSTO));
	//Wait untill Writing is complete
	//__delay_ms(34000);    //2.125mS failed for 2mS
	//Return TRUE on Success
	return TRUE;
		
}